﻿using Google.Protobuf;
using ProtoBuf;
using ProtoBuf.Meta;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lails.MQClient.Demo
{
    /// <summary>
    /// 谷歌序列化/反序列化帮助类
    /// </summary>
    public class ProtobufHelper
    {
        static ProtobufHelper()
        {
            //枚举类型注册
            //RuntimeTypeModel.Default[typeof(SexType)].EnumPassthru = true;
            
        }

        #region [ProtoContract] + [ProtoMember()]

        /// <summary>
        /// 谷歌序列化，适用于使用 [ProtoContract] + [ProtoMember()] 定义类的对象
        /// </summary> 
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="t">对象</param>
        /// <returns>序列化后的字节数组</returns>
        public static byte[] Serialize<T>(T t)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                Serializer.Serialize<T>(ms, t);
                return ms.ToArray();
            }
        }

        /// <summary>
        /// 谷歌反序列化，适用于使用 [ProtoContract] + [ProtoMember()] 定义类的对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="buffer">对象序列化字节数组</param>
        /// <returns>反序列化后的对象</returns>
        public static T DeSerialize<T>(byte[] buffer)
        {
            using (MemoryStream ms = new MemoryStream(buffer))
            {
                T t = Serializer.Deserialize<T>(ms);
                return t;
            }
        }


        #endregion

        #region .proto

        /// <summary>
        /// 谷歌序列化，适用于从.proto自动生成对象代码的定义类的序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static byte[] SerializeWriteTo<T>(T t) where T : IMessage<T>, new()
        {
            byte[] body = null;
            using (var stream = new MemoryStream())
            using (var output = new CodedOutputStream(stream))
            {
                t.WriteTo(output);
                output.Flush();
                body = stream.ToArray();
            }
            return body;
        }

        /// <summary>
        /// 谷歌反序列化，适用于从.proto自动生成对象代码的定义类的反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public static T DeSerializeParser<T>(byte[] buffer) where T : IMessage<T>, new()
        {
            var parser = new MessageParser<T>(() => new T());
            using (var input = new MemoryStream(buffer))
            {
                return (T)(parser.ParseFrom(input));
            }
        }

        #endregion
    }
}